//
// Created by Mechrevo on 2023/4/23.
//

#ifndef FACEVERIFY_RETINAFACE_H
#define FACEVERIFY_RETINAFACE_H

#include "opencv2/opencv.hpp"
#include "ncnn/net.h"
#include "mnet.25.id.h"
#include "mnet.25.mem.h"

using namespace std;
using namespace cv;



namespace retina {
    struct FaceObject {
        float prob = 0.0;
        int width = 0;
        int height = 0;
        std::string costTime = "";
        cv::Rect_<float> rect = {};
        cv::Point2f landmark[5] = {};
    };

    inline ncnn::Net* getModel() {  // 明确返回指针
        static std::unique_ptr<ncnn::Net> model;  // 智能指针管理
        static std::once_flag flag;
        std::call_once(flag, []() {
            model.reset(new ncnn::Net());  // 或使用 ncnn 的工厂方法
            model->opt.use_vulkan_compute = true;
            model->load_param("mnet_25_opt.param");
            model->load_model("mnet_25_opt.bin");
        });
        return model.get();  // 返回原始指针（需确保调用方不删除）
    }


    vector<int> resize_letter(Mat &image, float new_shape = 32 * 20);

    static inline float intersection_area(const FaceObject &a, const FaceObject &b) {
        cv::Rect_<float> inter = a.rect & b.rect;
        return inter.area();
    }

    cv::Mat draw_face_objects(const cv::Mat &bgr, const std::vector<FaceObject> &faceobjects);

    void retina_face_predict(cv::Mat &image, vector<FaceObject> &face_objects);

}
#endif //FACEVERIFY_RETINAFACE_H
